package com.hoshiicloud.mallshop.service.impl.goodsmanage;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hoshiicloud.auth.vo.TokenUsersVO;
import com.hoshiicloud.common.constant.BaseSkuDistributorEnum;
import com.hoshiicloud.common.constant.DeleteStatusEnum;
import com.hoshiicloud.common.exception.CommonError;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.goods.entity.goods.GoodsGallery;
import com.hoshiicloud.goods.entity.sku.ExtSku;
import com.hoshiicloud.goods.entity.sku.ProductManage;
import com.hoshiicloud.goods.entity.spu.ExtSpu;
import com.hoshiicloud.goods.entity.spu.ExtSpuTags;
import com.hoshiicloud.goods.entity.spu.SpuSalesCategory;
import com.hoshiicloud.goods.param.sku.ExtSkuQueryParam;
import com.hoshiicloud.goods.param.sku.ProductManageQueryParam;
import com.hoshiicloud.goods.param.sku.SkuBaseListParam;
import com.hoshiicloud.goods.vo.sku.BaseSkuVo;
import com.hoshiicloud.mallshop.feign.ShopIdGeneratorService;
import com.hoshiicloud.mallshop.feign.ShopGoods2FeignService;
import com.hoshiicloud.mallshop.feign.ShopGoodsSpuSkuFeignService;
import com.hoshiicloud.mallshop.feign.ShopUserFeignService;
import com.hoshiicloud.user.entity.store.PlatStore;
import com.hoshiicloud.user.param.PlatStoreQueryParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author qry
 * @date 2019/9/10 14:36
 */
@Slf4j
@Service
public class BranchStoreProdSyncServiceImpl {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ShopUserFeignService lesseeUserFeignService;

    @Autowired
    private ShopIdGeneratorService idGeneratorService;

    @Autowired
    private ShopGoodsSpuSkuFeignService lesseeGoodsFeignService;

    @Autowired
    private ShopGoods2FeignService lesseeGoods2FeignService;

    public boolean syncMainStoreProduct(TokenUsersVO user) {
        Long mainStoreId = user.getStoreId();
        String name = user.getRealName();
        LocalDateTime now = LocalDateTime.now();
        this.lockTheSameStoreSync(mainStoreId); //锁定同一家总店的 同步操作
        try {
            List<Long> listBranchStoreIds = this.getPlatBranchStoreListIds(mainStoreId);//获取所有分店 id
            Map<String, List<String>> storeAndBaseSkuIds = this.getBranchStoreAndBaseSkus(listBranchStoreIds);//获取分店需要添加的sku 信息

            List<Long> listMainStoreBaseSkuIds = this.getMainStroreBaseSkusDis(mainStoreId) ;


            List<ExtSku> listExtsku = this.getMainStoreExtSkus(mainStoreId);// 获取总店的扩展sku信息

            List<ExtSpu> listExtspu =  this.getMainStoreExtSpus(mainStoreId);

            //Response<List<ExtSpu>> listExtspu = lesseeGoodsFeignService.listExtSpuByStoreId(mainStoreId);
            // log.error("总店ExtSpu:{}, ge{}",listExtspu.getData().size(),listExtspu.getData());

            ProductManageQueryParam productManageQueryParam = new ProductManageQueryParam();
            productManageQueryParam.setStoreId(mainStoreId);
            productManageQueryParam.setDeleted(DeleteStatusEnum.UN_DELETED.getCode());
            Response<List<ProductManage>> listProductManage = lesseeGoodsFeignService.listProductManageByParam(productManageQueryParam);
            //log.error("总店ProductManage:{},ge{}",listProductManage.getData().size(),listProductManage.getData());

            List<Long> listSpuIds = listExtspu.stream().map(ExtSpu::getId).collect(Collectors.toList());
            Response<List<SpuSalesCategory>> listSpuSalesCategory = lesseeGoods2FeignService.listSpuSalesCategoryBySpuIds(listSpuIds);
            //log.error("总店SpuSalesCategory:{},ge{}",listSpuSalesCategory.getData().size(),listSpuSalesCategory.getData());


            Response<List<ExtSpuTags>> listExtSpuTags = lesseeGoods2FeignService.listExtSpuTagsBySpuIds(listSpuIds);
            //log.error("总店ExtSpuTags:{},ge{}", listExtSpuTags.getData().size(), listExtSpuTags.getData());

            Response<List<GoodsGallery>> listGoodsGallery = lesseeGoods2FeignService.listGoodsGalleryBySpuIds(listSpuIds);
            //log.error("总店GoodsGallery:{},ge{}",listGoodsGallery.getData().size(),listGoodsGallery.getData());


            List<ExtSku> allExtSku = new ArrayList<>();
            List<ExtSpu> allExtSpu = new ArrayList<>();
            List<ProductManage> allProductManage = new ArrayList<>();
            List<SpuSalesCategory> allSpuSalesCategory = new ArrayList<>();
            List<ExtSpuTags> allExtSpuTags = new ArrayList<>();
            List<GoodsGallery> allGoodsGallery = new ArrayList<>();

            for (Long branchStoreId : listBranchStoreIds) {
                // 获取指定分店的商品信息（取得的是 分店的skuId以逗号分隔的字符串）
                List<String> storeBaseSkuIdS = storeAndBaseSkuIds.get(branchStoreId.toString());
                // 遍历总店的 ExtSku
                for (ExtSku extSku : listExtsku) {
                    //  如果该ExtSku在该分店不存在， 那么就得添加到该分店
                    if (null == storeBaseSkuIdS || !storeBaseSkuIdS.contains((extSku.getSkuId().toString()))) {
                        // id生成Ok
                        Long newExtSpuId = this.getId();
                        Long newExtSkuId = this.getId();

                        ExtSku brachExtsku = JSONObject.parseObject(JSONObject.toJSONString(extSku), ExtSku.class);
                        brachExtsku.setId(newExtSkuId).setSpuId(newExtSpuId)
                                .setStoreId(branchStoreId).setCreatedTime(now).setCreatedBy(name).setUpdatedTime(now).setUpdatedBy(name);
                        allExtSku.add(brachExtsku);

                        // 遍历总店的 ExtSpu
                        for (ExtSpu extSpu : listExtspu) {
                            if (extSpu.getId().longValue() == extSku.getSpuId().longValue()) {
                                ExtSpu brachExtSpu = JSONObject.parseObject(JSONObject.toJSONString(extSpu), ExtSpu.class);
                                brachExtSpu.setId(newExtSpuId).setStoreId(branchStoreId)
                                        .setCreatedTime(now).setCreatedBy(name)
                                        .setUpdatedTime(now).setUpdatedBy(name);
                                allExtSpu.add(brachExtSpu);
                            }
                        }

                        for (ProductManage productManage : listProductManage.getData()) {
                            if (productManage.getSkuId().longValue() == extSku.getId().longValue()) {
                                ProductManage brachProductManage = JSONObject.parseObject(JSONObject.toJSONString(productManage), ProductManage.class);
                                brachProductManage.setSkuId(newExtSkuId).setId(this.getId())
                                        .setStoreId(branchStoreId).setCreatedTime(now).setCreatedBy(name)
                                        .setUpdatedTime(now).setUpdatedBy(name);
                                allProductManage.add(brachProductManage);
                            }
                        }

                        for (SpuSalesCategory spuSalesCategory : listSpuSalesCategory.getData()) {
                            if (spuSalesCategory.getExtSpuId().longValue() == extSku.getSpuId().longValue()) {
                                SpuSalesCategory brachSpuSalesCategory = JSONObject.parseObject(JSONObject.toJSONString(spuSalesCategory), SpuSalesCategory.class);
                                brachSpuSalesCategory.setExtSpuId(newExtSpuId)
                                        .setId(this.getId()).setCreatedBy(name).setCreatedTime(now).setUpdatedTime(now).setUpdatedBy(name);
                                allSpuSalesCategory.add(brachSpuSalesCategory);
                            }

                        }

                        for (ExtSpuTags extSpuTags : listExtSpuTags.getData()) {
                            if (extSpuTags.getSpuId().longValue() == extSku.getSpuId().longValue()) {
                                ExtSpuTags brachExtSpuTags = JSONObject.parseObject(JSONObject.toJSONString(extSpuTags), ExtSpuTags.class);
                                brachExtSpuTags.setId(this.getId()).setSpuId(newExtSpuId).setCreatedBy(name).setCreatedTime(now).setUpdatedTime(now).setUpdatedBy(name);
                                allExtSpuTags.add(brachExtSpuTags);
                            }

                        }


                        for (GoodsGallery goodsGallery : listGoodsGallery.getData()) {
                            if (goodsGallery.getExtSpuId().longValue() == extSku.getSpuId().longValue()) {
                                GoodsGallery brachGoodsGallery = JSONObject.parseObject(JSONObject.toJSONString(goodsGallery), GoodsGallery.class);
                                brachGoodsGallery.setId(this.getId()).setExtSpuId(newExtSpuId).setCreatedTime(now).setUpdatedTime(now);
                                allGoodsGallery.add(brachGoodsGallery);
                            }
                        }
                    }

                }
            }

            this.saveALLSyncData(allExtSpu, allExtSku, allProductManage, allSpuSalesCategory, allExtSpuTags, allGoodsGallery);
        } catch (Exception e) {
            log.error("总店ID：" + mainStoreId + "同步失败", e);
            throw new ServiceException("同步失败：" + e.getMessage());
        } finally {
            redisTemplate.delete("mainStoreSyncProductToBranchStore" + mainStoreId);
        }
        return true;

    }
  /**
   * 2019/9/10 16:22 qry
   *
   **/
    private List<Long> getMainStroreBaseSkusDis(Long mainStoreId){
        SkuBaseListParam p = new SkuBaseListParam();
        p.setStoreId(mainStoreId);
        p.setDeleted(DeleteStatusEnum.UN_DELETED.getCode());
        p.setDistributorStatu(BaseSkuDistributorEnum.YES.getCode());
        Response<List<BaseSkuVo>> rs = lesseeGoodsFeignService.listBaseSkuByParam(p);
        if(null == rs || rs.getCode() !=200 || null == rs.getData() ){
            throw new ServiceException("获取总店分销属性的BaseSku信息失败");
        }
        List<Long> list = rs.getData().stream().map(BaseSkuVo::getId).collect(Collectors.toList());
        return list;
    }

    private List<ExtSpu> getMainStoreExtSpus(Long mainStoreId) {
        Response<List<ExtSpu>> rs = lesseeGoodsFeignService.listExtSpuByStoreId(mainStoreId);
        if(null == rs || rs.getCode() !=200 || null == rs.getData() ){
            throw new ServiceException("获取总店分销商品信息失败");
        }
        return rs.getData();
    }

    private List<ExtSku> getMainStoreExtSkus(Long mainStoreId) {
        ExtSkuQueryParam extSkuQueryParam = new ExtSkuQueryParam();
        extSkuQueryParam.setStoreId(mainStoreId);
        extSkuQueryParam.setDeleted(DeleteStatusEnum.UN_DELETED.getCode());
        Response<List<ExtSku>> rs = lesseeGoodsFeignService.listExtSkuByParam(extSkuQueryParam);
        if(null == rs || rs.getCode() !=200 || null == rs.getData() ){
            throw new ServiceException("获取总店分销商品信息失败");
        }
        return rs.getData();
    }

    private Map<String, List<String>> getBranchStoreAndBaseSkus(List<Long> listBranchStoreIds) {
        Response<Map<String, List<String>>> rs = lesseeGoodsFeignService.queryExtskuAndBaseSkuIds(listBranchStoreIds);
        if(null == rs || rs.getCode() !=200 || null == rs.getData() ){
            throw new ServiceException("获取各分店已同步的sku信息失败");
        }
        return rs.getData();
    }

    private List<Long> getPlatBranchStoreListIds(Long mainStoreId) {
        PlatStoreQueryParam param = new PlatStoreQueryParam();
        param.setPageNumber("1");
        param.setPageSize("10000");
        param.setParentId(mainStoreId);
        Response<Page<PlatStore>> rsPage = lesseeUserFeignService.getPlatStorePage(param);
        if(null == rsPage || rsPage.getCode() !=200 || null == rsPage.getData() ){
            throw new ServiceException("获取分店信息失败");
        }
        List<Long> ids = rsPage.getData().getRecords().stream().map(PlatStore::getId).collect(Collectors.toList());
        return ids;
    }

    /**
     * @Author qry
     * @Date 14:56 2019/9/10
     * 锁定同一家店的同步按钮操作
     **/
    private void lockTheSameStoreSync(Long mainStoreId) {
        if (redisTemplate.hasKey("mainStoreSyncProductToBranchStore" + mainStoreId)) {
            throw new ServiceException("本店已有操作员在同步商品到分店，请稍后再操作");
        }
        redisTemplate.opsForValue().set("mainStoreSyncProductToBranchStore" + mainStoreId, 1, 1, TimeUnit.DAYS);
    }

    /**
     * @Author qry
     * @Date 15:11 2019/8/9
     * ID 生成器
     **/
    private Long getId() {
        String id = idGeneratorService.queryGeneratorId();
        if (StrUtil.isBlank(id)) {
            throw new ServiceException(CommonError.error("主键ID生成失败"));
        }
        return Long.valueOf(id);
    }

    private void saveALLSyncData(List<ExtSpu> allExtSpu, List<ExtSku> allExtSku,
                                 List<ProductManage> allProductManage, List<SpuSalesCategory> allSpuSalesCategory,
                                 List<ExtSpuTags> allExtSpuTags, List<GoodsGallery> allGoodsGallery) {
        lesseeGoodsFeignService.saveExtSpuBatch(allExtSpu);
        lesseeGoodsFeignService.saveExtSkuBatch(allExtSku);
        lesseeGoodsFeignService.saveProductManageBatch(allProductManage);
        lesseeGoods2FeignService.saveSpuSalesCategoryBatch(allSpuSalesCategory);
        lesseeGoods2FeignService.saveExtSpuTagsBatch(allExtSpuTags);
        lesseeGoods2FeignService.saveGoodsGalleryBatch(allGoodsGallery);
    }

}
